package othello.players.learnplayers;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import othello.model.Action;
import othello.model.IBoard;
import othello.neuralnetwork.NeuralNetwork;
import othello.players.AbstractPlayer;

public abstract class AbstractNeuralNetworkPlayer extends AbstractPlayer {
	public enum BenchmarkState { Training, Benchmarking, Playing};
    protected final NeuralNetwork nn;
	protected double nnLR;
	protected boolean useEligibility;
	protected BenchmarkState benchmarkState;
	protected int totalGames = -1;
	private boolean loadWeights;
    private boolean saveWeights;
    
    public AbstractNeuralNetworkPlayer(String name, NeuralNetwork neuralNetwork) {
    	super(name);
    	this.nn = neuralNetwork;
    }
    
    public void setState(BenchmarkState benchmarkState) {
    	this.benchmarkState = benchmarkState;
    }
    
    public final void setUseEligibility(boolean enabled) {
    	this.useEligibility = enabled;
    }
    
    public final void setNNLearningRate(double learningRate) {
    	this.nnLR = learningRate;
    }
    
    public final void setLoadWeights(boolean enabled) {
    	this.loadWeights = enabled;
    }
	
    public final void setSaveWeights(boolean enabled) {
	   	this.saveWeights = enabled;
	}

	public final void loadWeights() {
		if (loadWeights)
	    	this.nn.loadWeights(name);
	}
	    
    public final void saveWeights() {
    	if (saveWeights)
    		this.nn.saveWeights(name);
    }
    
    protected int actionIndex(Action a) {
        return 8 * a.getRow() + a.getCol();
    } 

    
    protected byte[][] cloneByteArray(byte[][] bytes) {
    	byte[][] copy = new byte[bytes.length][bytes.length];
    	for(int row = 0;row < bytes.length;row++) {
    		for(int col = 0;col < bytes[row].length;col++) {
				if (getColor() == Color.WHITE){
					copy[row][col] = bytes[row][col];
					//System.out.print("White board copy: " + copy[4][4] + ", byte: " + bytes[4][4]);
				} else {
					if (bytes[row][col] == 1){
						copy[row][col] = -1;
					}
					else if (bytes[row][col] == -1){
						copy[row][col] = 1;
					} 
					else {
						copy[row][col] = 0;
					}
					
					//System.out.print("Black board copy: " + copy[4][4] + ", byte: " + bytes[4][4]);
				}					
    		}
    	}
    	return copy;
    }
    
    protected double reward(IBoard brd) {
        if (brd.isGameOver()){        
            if(brd.playerScore(Color.DARK_GRAY) > brd.playerScore(Color.WHITE)) {
                if(getColor() == Color.DARK_GRAY) {
                    return 1.0;
                } else if(getColor() == Color.WHITE){
                    return 0.0;
                }
            } else if(brd.playerScore(Color.DARK_GRAY) < brd.playerScore(Color.WHITE)) {
                if(getColor() == Color.DARK_GRAY) {
                    return 0.0;
                } else if(getColor() == Color.WHITE){
                    return 1.0;
                }
            } else if(brd.playerScore(Color.DARK_GRAY) == brd.playerScore(Color.WHITE)) {
                return 0.5;
            }
        }
        return 0.5;
    }
}
